void main() {
  SingerDancer().performerMethod();

}
//https://dart.cn/language/mixins/#specify-members-a-mixin-can-call-on-itself
mixin Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    if (canPlayPiano) {
      print('Playing piano');
    } else if (canConduct) {
      print('Waving hands');
    } else {
      print('Humming to self');
    }
  }
}



//https://dart.cn/language/mixins/#define-abstract-members-in-the-mixin
mixin Musician {
  void playInstrument(String instrumentName); // Abstract method.

  void playPiano() {
    playInstrument('Piano');
  }
  void playFlute() {
    playInstrument('Flute');
  }
}

class Virtuoso with Musician { 

  @override
  void playInstrument(String instrumentName) { // Subclass must define.
    print('Plays the $instrumentName beautifully');
  }  
}

//https://dart.cn/language/mixins/#access-state-in-the-mixins-subclass
/// Can be applied to any type with a [name] property and provides an
/// implementation of [hashCode] and operator `==` in terms of it.
mixin NameIdentity {
  String get name;

  @override
  int get hashCode => name.hashCode;

  @override
  bool operator ==(other) => other is NameIdentity && name == other.name;
}

class Person with NameIdentity {
  final String name;

  Person(this.name);
}


//https://dart.cn/language/mixins/#implement-an-interface
abstract interface class Tuner {
  void tuneInstrument();
}

mixin Guitarist implements Tuner {
  void playSong() {
    tuneInstrument();

    print('Strums guitar majestically.');
  }
}

class PunkRocker with Guitarist {

  @override
  void tuneInstrument() {
    print("Don't bother, being out of tune is punk rock.");
  }
}


//https://dart.cn/language/mixins/#use-the-on-clause-to-declare-a-superclass
class Musicians {
  musicianMethod() {
    print('Playing music!');
  }
}

mixin MusicalPerformer on Musicians {
  performerMethod() {
    print('Performing music!');
    super.musicianMethod();
  }
}

class SingerDancer extends Musicians with MusicalPerformer {}




//https://dart.cn/language/mixins/#class-mixin-or-mixin-class
mixin class Musiciana {
  // ...
}

class Novice with Musiciana { // Use Musician as a mixin
  // ...
}

class Novices extends Musiciana { // Use Musician as a class
  // ...
}